/**
 * Copyright (c) 2009 Teoti Graphix, LLC See:
 *     http://tkarchitecture.teotigraphix.org
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 * 
 * @author Michael Schmalle mschmalle@teotigraphix.com
 */
package test.suite.dxframework.patterns.component
{

import mx.events.FlexEvent;

import org.flexunit.Assert;
import org.flexunit.async.Async;
import org.fluint.uiImpersonation.UIImpersonator;
import org.teotigraphix.dx.core.ToolKitGlobals;
import org.teotigraphix.dx.core.ToolKitUtil;
import org.teotigraphix.dx.patterns.manager.meta.ClassMetaData;
import org.teotigraphix.dx.patterns.manager.meta.SkinPartInfo;
import org.teotigraphix.dx.patterns.manager.meta.SkinStateInfo;

import test.suite.dxframework.support.behavior.TestBehavior;
import test.suite.dxframework.support.component.TestSkinStateComponent;
import test.suite.dxframework.support.skin.TestComponentSkin;

public class TC_DXComponent_States
{
	protected var component:TestSkinStateComponent;
	protected var behavior:TestBehavior;
	
	[Before(ui,async)]
	public function setUp():void
	{
		ToolKitGlobals.VALIDATION_EVENTS_ENABLED = true;
		
		component = new TestSkinStateComponent();
		behavior = new TestBehavior();
		
		Async.proceedOnEvent(this, component, FlexEvent.CREATION_COMPLETE);
		UIImpersonator.addChild( component );
	}
	
	[After]
	public function tearDown():void
	{
		UIImpersonator.removeChild( component );
		component = null;
		behavior = null;
	}
	
	[Test]
	/**
	 * Tests 
	 */
	public function test_SkinState_metadata():void
	{
		var data:ClassMetaData = ToolKitUtil.resolveClassMetaData( component );
		var meta:SkinStateInfo = data.getSkinStateInfoByID( "normal" );
		
		Assert.assertNotNull( "SkinStateInfo null", meta );
		Assert.assertEquals( "", "normal", meta.id );
		
		meta = data.getSkinStateInfoByID( component.STATE_ONE );
		Assert.assertNotNull( "STATE_ONE null", meta );
		Assert.assertEquals( "", component.STATE_ONE, meta.id );
		
		meta = data.getSkinStateInfoByID( component.STATE_TWO );
		Assert.assertNotNull( "STATE_TWO null", meta );
		Assert.assertEquals( "", component.STATE_TWO, meta.id );
		
		meta = data.getSkinStateInfoByID( component.STATE_THREE );
		Assert.assertNotNull( "STATE_THREE null", meta );
		Assert.assertEquals( "", component.STATE_THREE, meta.id );				
	}
	
	// FIXME (mschmalle) need to use [SkinPartAlias] Flex 4 compiler mess things up
	// with [SkinPart] 
	//[Test]
	/**
	 * Tests 
	 */
	public function test_SkinPart_metadata():void
	{
		// FIXME (mschmalle) Remove in ComponentBehavior where you are setting these
		// since you now have these parts, they can be set by some other abstract means
		var data:ClassMetaData = ToolKitUtil.resolveClassMetaData( component );
		var meta:SkinPartInfo = data.getSkinPartInfoByID( "mySkinPart" );
		Assert.assertNotNull( "SkinPartInfo null", meta );
		
		meta = data.getSkinPartInfoByID( "mySubclassSkinPart" );
		Assert.assertNotNull( "SkinPartInfo null", meta );
	}
	
	[Test]
	/**
	 * Tests 
	 */
	public function test_call_invalidateState():void
	{
		Assert.assertFalse( "component.invalidateSkinFlag", component.invalidateSkinFlag );
		component.invalidateSkin();
		Assert.assertTrue( "!component.invalidateSkinFlag", component.invalidateSkinFlag );
	}
	
	[Test]
	/**
	 * Tests 
	 */
	public function test_set_state_change():void
	{
		// I want to test the use of ISkinStateAware.invalidateState()
		// this should be simple and make use of the component's
		// 'coreSkin'.currentState
		// for now I'm using validateNow(), change this
		
		var skin:TestComponentSkin = component.coreSkin as TestComponentSkin;
		
		Assert.assertEquals( "", "normal", component.currentState );
		Assert.assertEquals( "", "normal", skin.currentState );	
		
		component.inStateOne = true;
		component.validateNow();
		
		Assert.assertEquals( "", component.STATE_ONE, component.currentState );
		Assert.assertEquals( "", component.STATE_ONE, skin.currentState );
		
		component.inStateTwo = true;
		component.validateNow();
		
		Assert.assertEquals( "", component.STATE_TWO, component.currentState );
		Assert.assertEquals( "", component.STATE_TWO, skin.currentState );
		
		component.inStateThree = true;
		component.validateNow();
		
		Assert.assertEquals( "", component.STATE_THREE, component.currentState );
		Assert.assertEquals( "", component.STATE_THREE, skin.currentState );	
		
	}
}
}